package com.yst.webplugin.fieldhandler;

import com.yst.spring.context.SpringContext;
import com.yst.web.utils.ClassUtils;
import com.yst.webplugin.annotation.Command;
import com.yst.webplugin.annotation.HttpInfo;
import com.yst.webplugin.annotation.ICommand;
import com.yst.webplugin.util.ParamUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.sagacity.sqltoy.dao.SqlToyLazyDao;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
public class CommandHandler implements IFieldHandler{
    @Override
    public boolean accept(Field field) {
        return Objects.nonNull(field.getAnnotation(Command.class));
    }

    private long executeSQL(Field field,String sqlOrName,HttpInfo httpInfo){
        Map<String,Object> params=httpInfo.getBodyAs(HashMap.class);
        SqlToyLazyDao sqlToyLazyDao= SpringContext.getContext().getBean(SqlToyLazyDao.class);
        return sqlToyLazyDao.executeSql(sqlOrName, params);
    }

    @SneakyThrows
    @Transactional
    @Override
    public void handle(Field field, HttpInfo httpInfo) {
        Command command=field.getAnnotation(Command.class);

        Map<String,Object> params=httpInfo.getBodyAs(HashMap.class);
        ParamUtils.checkParams(params,command.validClass(),command.validClassGroup());

        long result=0;
        Class<? extends ICommand> iCommand=command.executor();
        if (iCommand!= ICommand.class){
            ICommand commandInstance=SpringContext.getContext().getBean(iCommand);
            result = commandInstance.execute(httpInfo);
        }
        else {
            result=executeSQL(field, command.commandName(), httpInfo);
        }

        if (ClassUtils.isAssignableFrom(field.getType(), Integer.class, Long.class)) {
            httpInfo.writeResult(result);
            return;
        }
        if (ClassUtils.isAssignableFrom(field.getType(), Boolean.class, boolean.class)) {
            httpInfo.writeResult(result!=0);
        }
    }
}
